home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / Macintosh Drag and Drop / Demo Applications / FinderDrag / Exceptions.h next >
Encoding:
C/C++ Source or Header  |  1995-06-09  |  29.3 KB  |  1,014 lines  |  [TEXT/MPS ]

  1.  
  2. /*********************************************************************
  3.  
  4. FILENAME
  5.     Exceptions.h
  6.     
  7. DESCRIPTION
  8.     A collection of routines and macros to handle assertions and
  9.     exceptions.
  10.  
  11. COPYRIGHT
  12.     Copyright © Apple Computer, Inc. 1989-1991
  13.     All rights reserved.
  14.  
  15. ROUTINES
  16.     EXTERNALS
  17.         dprintf
  18.         check_dprintf
  19.         checkpos_dprintf
  20.  
  21. MACROS
  22.     EXTERNALS
  23.         check
  24.         ncheck
  25.         check_action
  26.         ncheck_action
  27.         require
  28.         nrequire
  29.         require_action
  30.         nrequire_action
  31.         resume
  32.  
  33. MODIFICATION HISTORY
  34.     08/03/89    Sean Parent
  35.         1)    Version 1.0d1 started
  36.     09/26/89    sp
  37.         1)    Corrected the description of require
  38.     12/08/89    sp
  39.         1)    Ported from XXXX Exceptions.h
  40.     03/16/90    sp
  41.         1)    Removed refCon parameter
  42.         2)    Added the "n" calls
  43.     05/10/90    sp
  44.         1)    Added the dprintf call and revved other macros to use it.
  45.     06/12/90    sp
  46.         1)    Modified the dprint off to use a macro for traceOption.
  47.     08/01/90    sp
  48.         1)    Modified for C++ compatibility (Thanks Ron).
  49.     08/14/90    sp
  50.         1)    Added action calls.
  51.     09/20/90    sp
  52.         1)    Removed rescue_ prefix in require exception labels.
  53.     01/16/91    sp
  54.         1)    Fixed some comments and updated the copyright notice.
  55.     02/13/91    sp
  56.         1)    Added check_action and ncheck_action calls.
  57.         2)    Added SetExceptionOption
  58.     02/22/91    sp
  59.         1)    Added {} around all macros just to be defensive for TED.
  60.         2)    Put everything in "if (true) { MACRO } else" form to be very
  61.             defensive.
  62.     02/26/91    sp
  63.         1)    Added a null statement after the else of each macro for the
  64.             fools who forgot to put ; in.
  65.     03/13/91    sp
  66.         1)    Added void* cast for privateAssertion for C++.
  67.     03/13/91    sp/NB
  68.         1)    Fixed void* cast for privateAssertion for C++.
  69.     11/04/91    sp
  70.         1)    Removed retry.
  71.         2)    Added DEBUGMIN support.
  72.         3) Removed SetExceptionOption.
  73.         4) Cleaned up for Develop article.
  74.     11/05/91    sp
  75.         1)    Removed PlaceHolder() and moved to "do { MACRO } while(false)"
  76.     11/19/91 sp
  77.         1)    Added DEBUGSYM level.
  78.         
  79. NOTE
  80.     To keep code size down, use these routines and macros with the C
  81.     compiler option -b2 or -b3. This will eliminate duplicate strings
  82.     within a procedure.
  83.  
  84. *********************************************************************/
  85.  
  86. #ifndef __EXCEPTIONS__
  87. #define __EXCEPTIONS__
  88.  
  89. /*********************************************************************
  90.  
  91. INCLUDES
  92.  
  93. *********************************************************************/
  94.  
  95. #ifndef    __TYPES__
  96. #include <Types.h>
  97. #endif
  98. /*<FF>*/
  99. /*********************************************************************
  100.  
  101. CONSTANTS AND CONTROL
  102.  
  103. *********************************************************************/
  104.  
  105. /*
  106.     These defines are used to control the amount of information
  107.     displayed when an assertion fails. DEBUGOFF and WARN will run
  108.     silently. MIN will simply break into the debugger. ON will break
  109.     and display the assertion that failed and the exception (for
  110.     require statements). FULL will also display the source file name
  111.     and line number. SYM does a SysBreak and is usefull when using a
  112.     symbolic debugger like SourceBug or SADE. They should be set into
  113.     DEBUGLEVEL. The default LEVEL is OFF.
  114. */
  115.  
  116. #define DEBUGOFF        0
  117. #define DEBUGWARN        1
  118. #define DEBUGMIN        2
  119. #define DEBUGON        3
  120. #define DEBUGFULL        4
  121. #define DEBUGSYM        6
  122. #define DEBUGWINDOW        101
  123. #define DEBUGNICE        99
  124. #ifndef    DEBUGLEVEL
  125. #define    DEBUGLEVEL    DEBUGOFF
  126. #endif    DEBUGLEVEL
  127.  
  128. #if DEBUGLEVEL == DEBUGWINDOW
  129.     #include "wprintf.h"
  130. #endif
  131.  
  132.  
  133. /*
  134.     resumeLabel is used to control the insertion of labels for use with
  135.     the resume macro. If you do not use the resume macro and you wish
  136.     to have multible exceptions per label then you can add the
  137.     following define to you source code.
  138.     
  139.     #define resumeLabel(exception)
  140. */
  141.  
  142. #define resumeLabel(exception)    resume_ ## exception:
  143.  
  144. /*
  145.     trace and notrace are used for the traceOption for dprintf. If
  146.     trace is used then the actual behavior can be controled from
  147.     Macsbug. The macros in Macsbug are traceGo and traceBreak. traceGo
  148.     is the default and execution will continue after the break. If
  149.     traceBreak is used then execution will halt.
  150. */
  151.  
  152. #define    trace        "\p;dprintf;doTrace"
  153. #define    notrace    "\p;dprintf"
  154.  
  155. /*
  156.     traceon and debugon are used to test for options
  157. */
  158.  
  159. #define    traceon    ((DEBUGLEVEL > DEBUGWARN) && defined(TRACEON))
  160. #define    debugon    (DEBUGLEVEL > DEBUGWARN)
  161.  
  162. /*
  163.     Add some macros for DEBUGMIN and DEBUGSYM to keep the size down.
  164. */
  165.  
  166. #define    __DEBUGSMALL    ((DEBUGLEVEL == DEBUGMIN) ||            \
  167.                                  (DEBUGLEVEL == DEBUGSYM))
  168.  
  169. #if    DEBUGLEVEL == DEBUGMIN
  170. #define    __DebuggerBreak    Debugger()
  171. #elif    DEBUGLEVEL == DEBUGSYM
  172. #define  __DebuggerBreak    SysBreak()
  173. #endif
  174.  
  175. /*<FF>*/
  176. /*********************************************************************
  177.  
  178. ROUTINE
  179.     void dprintf(traceOption, format, ...)
  180.  
  181. DESCRIPTION
  182.     dprintf is used like printf only the information is displayed in
  183.     MacsBug. traceOption is used to specify whether the execution
  184.     should continue after the break or not. format contains
  185.     two types of objects: ordinary characters, which are displayed in
  186.     Macsbug, and coversion specifications, each of which causes
  187.     conversion and printing of the next successive argument to dprintf.
  188.     Each conversion specification begins with a % and ends with a
  189.     conversion character. Between % and the conversion character there
  190.     may be, in order:
  191.     
  192.     •    Zero or more flag characters, which modify the meaning of the
  193.         conversion specification.
  194.     •    A number that specifies the minimum field width. The converted
  195.         argument will be printed in a field at least this wide. If
  196.         necessary it will be padded on the left (or right, if left
  197.         adjustment is called for) to make up the field width.
  198.     •    A period, which separates the field width from the precision.
  199.     •    A number, the precision, that specifies the maximum number of
  200.         characters to be printed from a string, or the number of digits
  201.         after the decimal point of a floatingpoint value, or the minimum
  202.         number of digits for an integer.
  203.     •    An h if the integer is to be printed as a short, or l if as
  204.         long (ignored since int is long), or L to specify that the
  205.         following e, E, f, g, or G conversion is a long double.
  206.     
  207.     Note: A field width or precision may be indicated by an * instead
  208.     of a digit string. In this case, an integer arg parameter supplies
  209.     the field width or precision. The arg parameter that is actually
  210.     converted is not fetched until the conversion letter is seen;
  211.     therefore, the arg paramters specifying field width or precision
  212.     must appear immediately before the arg parameter (if any) to be
  213.     converted.
  214.     
  215.     The flag characters are:
  216.     
  217.         -        The result of the conversion will be left justified
  218.                 within the field.
  219.         +        The result of a signed conversion always begins with a
  220.                 sign (+ or -).
  221.         space    If the first character of a signed conversion is not a
  222.                 sign, a space will be prefixed to the result. This implies
  223.                 that if the space and + flags both appear, the space flag
  224.                 will be ignored.
  225.         #        The value is to be converted to an alternate form. For c,
  226.                 d, s, and u conversions, the flag has no effect. For o
  227.                 conversions, it increases the precision to force the first
  228.                 digit of the result to be zero. For x, and X conversions,
  229.                 a nonzero result will have 0x or 0X prefixed to it. For
  230.                 e, E, f, g, and G conversions, the result will always
  231.                 contain a decimal point, even if no digits follow the
  232.                 point. For g and G conversion, trailing zeros in the
  233.                 fractional part will not be removed from the result.
  234.         0        The 0 flag pads the field with zeros on the left only;
  235.                 this applies to d, i, o, u, x, X, e, E, f, g, and G
  236.                 conversions. The leading zeros pad the field width, and
  237.                 no space padding is performed. If both the 0 and - flags
  238.                 appear, the 0 flag is ignored. If a precision is specified
  239.                 for d, i, o, u, x, and X conversions, the 0 flag is
  240.                 ignored.
  241.     
  242.     The standard conversions are:
  243.     
  244.         d,i        int            Decimal number.
  245.         o        int            Unsigned octal number (w/o a leading zero).
  246.         x,X        int            Unsigned hexadecimal number (w/o a leading 0x
  247.                                 or oX), using abcdef or ABCDEF for 10,…,15.
  248.         u        int            Unsigned decimal number.
  249.         c        int            Single character.
  250.         s        char*            C string.
  251.         f        double        [-]m.dddddd, where the number of d's is given
  252.                                 by the precision (default 6).
  253.         e,E        double        [-]m.dddddde±xx or [-]m.ddddddE±xx, where the
  254.                                 number of d's is given by the precision
  255.                                 (default 6).
  256.         g,G        double        Use %e or %E if the exponent is less than -4
  257.                                 or greater than or equal to the precision;
  258.                                 otherwise use %f. Trailing zeros and a
  259.                                 trailing decimal point are not printed.
  260.         p        void*            Pointer.
  261.         %                        No argument is converted; print a %.
  262.     
  263.     The supported MPW extensions are:
  264.     
  265.         P        StringPtr    Pascal string.
  266.     
  267.     Of the MPW printf convertion characters only "n" is not supported.
  268.     In addition to the standard characters, the following are defined:
  269.     
  270.         b        Boolean        Outputs either true or false.
  271.         j        Point            Used like the d option.
  272.         J        point*        Fixed point. Used like the f option.
  273.         F        Fixed            Used like the f option.
  274.         T        Fract            Used like the f option.
  275.         r        Rect*            Displays the rect with each piece seperated by
  276.                                 ", ". Used like the d option.
  277.         R        rectangle*    Similar to r but for fixed point rectangles.
  278.                                 Used like the f option.
  279.         M        mapping.        Displays the mapping seperated by ", " and
  280.                                 "\n". The third column is displayed as fract.
  281.                                 Used like the f option.
  282.     
  283.         
  284.     dprintf requires that the MacsBug dcmd dprintf is present.
  285.     
  286.     Characters used:     bcdefghij l nop rs u  x
  287.                                 EFG  J LM  P R T   X
  288.     Not used:            a         k m   q  t vw yz
  289.                             ABCD   HI K  NO Q S UVW YZ
  290.     
  291.     See the MPW C Reference for more information on printf.
  292.  
  293. Echo "                                                            ∂n∂
  294.     PRINT            OFF,NOHDR                                    ∂n∂
  295.     INCLUDE        'Traps.a'                                    ∂n∂
  296.     PRINT            ON                                                ∂n∂
  297.     PROC                                                            ∂n∂
  298.     _DebugStr                                                    ∂n∂
  299.     SUBQ            #4,SP        ; Fix the stack                ∂n∂
  300.     ENDPROC                                                        ∂n∂
  301.     END                                                            ∂n∂
  302. " | Asm -l
  303.  
  304. *********************************************************************/
  305.  
  306. void dprintf(StringPtr, char[], ...)
  307.     = { 0xABFF, 0x594F };
  308.  
  309. /*<FF>*/
  310. /*********************************************************************
  311.  
  312. ROUTINE
  313.     void* check_dprintf(assertion, traceOption, format, ...)
  314.  
  315. DESCRIPTION
  316.     If assertion is non-zero then assertion is returned. Otherwise the
  317.     dprintf is invoked and zero is returned.
  318.     
  319. Echo "                                                            ∂n∂
  320.     PRINT            OFF,NOHDR                                    ∂n∂
  321.     INCLUDE        'Traps.a'                                    ∂n∂
  322.     PRINT            ON                                                ∂n∂
  323.     PROC                                                            ∂n∂
  324.     MOVE.L        (SP)+,D0    ; Pop value into D0            ∂n∂
  325.     BNE.S            @1            ; If !0 then branch            ∂n∂
  326.     _DebugStr                                                    ∂n∂
  327.     SUBQ            #4,SP        ; Fix the stack                ∂n∂
  328.     CLR.W            D0            ; Result is zero                ∂n∂
  329. @1    SUBQ            #4,SP        ; Fix stack for pop            ∂n∂
  330.     ENDPROC                                                        ∂n∂
  331.     END                                                            ∂n∂
  332. " | Asm -l
  333.     
  334. *********************************************************************/
  335.     
  336. void* check_dprintf(void*, StringPtr, char[], ...) =
  337.     { 0x201F, 0x6606, 0xABFF, 0x594F, 0x4240, 0x594F };
  338.     
  339. /*<FF>*/
  340. /*********************************************************************
  341.  
  342. ROUTINE
  343.     void* checkpos_dprintf(assertion, traceOption, format, ...)
  344.  
  345. DESCRIPTION
  346.     If assertion is positive then assertion is returned. Otherwise the
  347.     dprintf is invoked and zero is returned.
  348.     
  349. Echo "                                                            ∂n∂
  350.     PRINT            OFF,NOHDR                                    ∂n∂
  351.     INCLUDE        'Traps.a'                                    ∂n∂
  352.     PRINT            ON                                                ∂n∂
  353.     PROC                                                            ∂n∂
  354.     MOVE.L        (SP)+,D0    ; Pop value into D0            ∂n∂
  355.     BGE.S            @1            ; If >= 0 then branch        ∂n∂
  356.     _DebugStr                                                    ∂n∂
  357.     SUBQ            #4,SP        ; Fix the stack                ∂n∂
  358.     CLR.W            D0            ; Result is zero                ∂n∂
  359. @1    SUBQ            #4,SP        ; Fix stack for pop            ∂n∂
  360.     ENDPROC                                                        ∂n∂
  361.     END                                                            ∂n∂
  362. " | Asm -l
  363.     
  364. *********************************************************************/
  365.     
  366. void* checkpos_dprintf(void*, StringPtr, char[], ...) =
  367.     { 0x201F, 0x6C06, 0xABFF, 0x594F, 0x4240, 0x594F };
  368.  
  369. /*<FF>*/
  370. /*********************************************************************
  371.  
  372. MACRO
  373.     check(assertion)
  374.  
  375. DESCRIPTION
  376.     If debugging is on then check will test assertion and if it fails
  377.     break into the debugger. Otherwise check does nothing.
  378.  
  379. *********************************************************************/
  380.  
  381. #if    __DEBUGSMALL
  382.  
  383. #define check(assertion)                                                            \
  384.     do {                                                                                    \
  385.         if (assertion) ;                                                                \
  386.         else __DebuggerBreak;                                                        \
  387.     } while (false)
  388.  
  389. #elif    DEBUGLEVEL == DEBUGON
  390.  
  391. #define check(assertion)                                                            \
  392.     do {                                                                                    \
  393.         if (assertion) ;                                                                \
  394.         else {                                                                            \
  395.             dprintf(notrace, "Assertion \"%s\" Failed",    #assertion);    \
  396.         }                                                                                    \
  397.     } while (false)
  398.  
  399. #elif    DEBUGLEVEL == DEBUGFULL
  400.  
  401. #define check(assertion)                                                            \
  402.     do {                                                                                    \
  403.         if (assertion) ;                                                                \
  404.         else {                                                                            \
  405.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  406.                                     "File: %s\n"                                        \
  407.                                     "Line: %d",                                            \
  408.                 #assertion, __FILE__, __LINE__);                                    \
  409.         }                                                                                    \
  410.     } while (false)
  411.  
  412. #elif    DEBUGLEVEL == DEBUGWINDOW
  413.  
  414. #define check(assertion)                                                            \
  415.     do {                                                                                    \
  416.         if (assertion) ;                                                                \
  417.         else {                                                                            \
  418.             wprintf(                "Assertion \"%s\" Failed\n"                    \
  419.                                     "File: %s\n"                                        \
  420.                                     "Line: %d\n",                                        \
  421.                 #assertion, __FILE__, __LINE__);                                    \
  422.         }                                                                                    \
  423.     } while (false)
  424.  
  425. #else
  426.  
  427. #define check(assertion)
  428.  
  429. #endif
  430.  
  431. /*<FF>*/
  432. /*********************************************************************
  433.  
  434. MACRO
  435.     ncheck(assertion)
  436.  
  437. DESCRIPTION
  438.     If debugging is on then ncheck will test !assertion and if it fails
  439.     break into the debugger. Otherwise ncheck does nothing.
  440.  
  441. *********************************************************************/
  442.  
  443. #if    __DEBUGSMALL
  444.  
  445. #define ncheck(assertion)                                                            \
  446.     do {                                                                                    \
  447.         if (assertion) __DebuggerBreak;                                            \
  448.     } while (false)
  449.  
  450. #elif    DEBUGLEVEL == DEBUGON
  451.  
  452. #define ncheck(assertion)                                                            \
  453.     do {                                                                                    \
  454.         void*    __privateAssertion    = (void*)(assertion);                    \
  455.                                                                                             \
  456.         if (__privateAssertion) {                                                    \
  457.             dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed",        \
  458.                 #assertion, __privateAssertion);                                    \
  459.         }                                                                                    \
  460.     } while (false)
  461.  
  462. #elif    DEBUGLEVEL == DEBUGFULL
  463.  
  464. #define ncheck(assertion)                                                            \
  465.     do {                                                                                    \
  466.         void*    __privateAssertion    = (void*)(assertion);                    \
  467.                                                                                             \
  468.         if (__privateAssertion) {                                                    \
  469.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  470.                                     "File: %s\n"                                        \
  471.                                     "Line: %d",                                            \
  472.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  473.         }                                                                                    \
  474.     } while (false)
  475.  
  476. #elif    DEBUGLEVEL == DEBUGWINDOW
  477.  
  478. #define ncheck(assertion)                                                            \
  479.     do {                                                                                    \
  480.         void*    __privateAssertion    = (void*)(assertion);                    \
  481.                                                                                             \
  482.         if (__privateAssertion) {                                                    \
  483.             wprintf(                "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  484.                                     "File: %s\n"                                        \
  485.                                     "Line: %d",                                            \
  486.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  487.         }                                                                                    \
  488.     } while (false)
  489.  
  490. #else
  491.  
  492. #define ncheck(assertion)
  493.  
  494. #endif
  495.  
  496. /*<FF>*/
  497. /*********************************************************************
  498.  
  499. MACRO
  500.     check_action(assertion, action)
  501.  
  502. DESCRIPTION
  503.     If debugging is on then check_action will test assertion and if it
  504.     fails break into the debugger then execute action. Otherwise
  505.     check_action does nothing.
  506.     
  507. *********************************************************************/
  508.  
  509. #if    __DEBUGSMALL
  510.  
  511. #define check_action(assertion, action)                                        \
  512.     do {                                                                                    \
  513.         if (assertion) ;                                                                \
  514.         else {                                                                            \
  515.             __DebuggerBreak;                                                            \
  516.             { action }                                                                    \
  517.     } while (false)
  518.  
  519. #elif    DEBUGLEVEL == DEBUGON
  520.  
  521. #define check_action(assertion, action)                                        \
  522.     do {                                                                                    \
  523.         if (assertion) ;                                                                \
  524.         else {                                                                            \
  525.             dprintf(notrace, "Assertion \"%s\" Failed",    #assertion);    \
  526.             { action }                                                                    \
  527.         }                                                                                    \
  528.     } while (false)
  529.  
  530. #elif    DEBUGLEVEL == DEBUGFULL
  531.  
  532. #define check_action(assertion, action)                                        \
  533.     do {                                                                                    \
  534.         if (assertion) ;                                                                \
  535.         else {                                                                            \
  536.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  537.                                     "File: %s\n"                                        \
  538.                                     "Line: %d",                                            \
  539.                 #assertion, __FILE__, __LINE__);                                    \
  540.             { action }                                                                    \
  541.         }                                                                                    \
  542.     } while (false)
  543.  
  544. #elif    DEBUGLEVEL == DEBUGWINDOW
  545.  
  546. #define check_action(assertion, action)                                        \
  547.     do {                                                                                    \
  548.         if (assertion) ;                                                                \
  549.         else {                                                                            \
  550.             wprintf(                "Assertion \"%s\" Failed\n"                    \
  551.                                     "File: %s\n"                                        \
  552.                                     "Line: %d",                                            \
  553.                 #assertion, __FILE__, __LINE__);                                    \
  554.             { action }                                                                    \
  555.         }                                                                                    \
  556.     } while (false)
  557.  
  558. #else
  559.  
  560. #define check_action(assertion, action)
  561.  
  562. #endif
  563.  
  564. /*<FF>*/
  565. /**************************************************************************************
  566.  
  567. MACRO
  568.     ncheck_action(assertion, action)
  569.  
  570. DESCRIPTION
  571.     If debugging is on then ncheck_action will test !assertion and if
  572.     it fails break into the debugger then execute action. Otherwise
  573.     ncheck_action does nothing.
  574.  
  575. *********************************************************************/
  576.  
  577. #if    __DEBUGSMALL
  578.  
  579. #define ncheck_action(assertion, action)                                        \
  580.     do {                                                                                    \
  581.         if (assertion) {                                                                \
  582.             __DebuggerBreak;                                                            \
  583.             { action }                                                                    \
  584.         }                                                                                    \
  585.     } while (false)
  586.  
  587. #elif    DEBUGLEVEL == DEBUGON
  588.  
  589. #define ncheck_action(assertion, action)                                        \
  590.     do {                                                                                    \
  591.         void*    __privateAssertion    = (void*)(assertion);                    \
  592.                                                                                             \
  593.         if (__privateAssertion) {                                                    \
  594.             dprintf(notrace, "Assertion \"!(%s [= %#08X])\" Failed",        \
  595.                 #assertion, __privateAssertion);                                    \
  596.             { action }                                                                    \
  597.         }                                                                                    \
  598.     } while (false)
  599.  
  600. #elif DEBUGLEVEL == DEBUGFULL
  601.  
  602. #define ncheck_action(assertion, action)                                        \
  603.     do {                                                                                    \
  604.         void*    __privateAssertion    = (void*)(assertion);                    \
  605.                                                                                             \
  606.         if (__privateAssertion) {                                                    \
  607.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  608.                                     "File: %s\n"                                        \
  609.                                     "Line: %d",                                            \
  610.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  611.             { action }                                                                    \
  612.         }                                                                                    \
  613.     } while (false)
  614.  
  615. #elif DEBUGLEVEL == DEBUGWINDOW
  616.  
  617. #define ncheck_action(assertion, action)                                        \
  618.     do {                                                                                    \
  619.         void*    __privateAssertion    = (void*)(assertion);                    \
  620.                                                                                             \
  621.         if (__privateAssertion) {                                                    \
  622.             wprintf(                "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  623.                                     "File: %s\n"                                        \
  624.                                     "Line: %d",                                            \
  625.             #assertion, __privateAssertion, __FILE__, __LINE__);            \
  626.             { action }                                                                    \
  627.         }                                                                                    \
  628.     } while (false)
  629.  
  630. #else
  631.  
  632. #define ncheck_action(assertion, action)
  633.  
  634. #endif
  635.  
  636. /*<FF>*/
  637. /*********************************************************************
  638.  
  639. MACRO
  640.     require(assertion, exception)
  641.  
  642. DESCRIPTION
  643.     require will test assertion and if it fails:
  644.         break into the debugger if debugging is on.
  645.         goto exception.
  646.  
  647. *********************************************************************/
  648.  
  649. #if    __DEBUGSMALL
  650.  
  651. #define require(assertion, exception)                                            \
  652.     do {                                                                                    \
  653.         if (assertion) ;                                                                \
  654.         else {                                                                            \
  655.             __DebuggerBreak;                                                            \
  656.             goto exception;                                                            \
  657.             resumeLabel(exception);                                                    \
  658.         }                                                                                    \
  659.     } while (false)
  660.  
  661. #elif    DEBUGLEVEL == DEBUGON
  662.  
  663. #define require(assertion, exception)                                            \
  664.     do {                                                                                    \
  665.         if (assertion) ;                                                                \
  666.         else {                                                                            \
  667.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  668.                                     "Exception \"%s\" Raised",                        \
  669.             #assertion, #exception);                                                \
  670.             goto exception;                                                            \
  671.             resumeLabel(exception);                                                    \
  672.         }                                                                                    \
  673.     } while (false)
  674.  
  675. #elif DEBUGLEVEL == DEBUGFULL
  676.  
  677. #define require(assertion, exception)                                            \
  678.     do {                                                                                    \
  679.         if (assertion) ;                                                                \
  680.         else {                                                                            \
  681.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  682.                                     "Exception \"%s\" Raised\n"                    \
  683.                                     "File: %s\n"                                        \
  684.                                     "Line: %d",                                            \
  685.                 #assertion, #exception, __FILE__, __LINE__);                    \
  686.             goto exception;                                                            \
  687.             resumeLabel(exception);                                                    \
  688.         }                                                                                    \
  689.     } while (false)
  690.  
  691. #elif    DEBUGLEVEL == DEBUGWINDOW
  692. #define require(assertion, exception)                                            \
  693.     do {                                                                                    \
  694.         if (assertion) ;                                                                \
  695.         else {                                                                            \
  696.             wprintf(                "Assertion \"%s\" Failed\n"                    \
  697.                                     "Exception \"%s\" Raised\n"                    \
  698.                                     "File: %s\n"                                        \
  699.                                     "Line: %d\n",                                        \
  700.                 #assertion, #exception, __FILE__, __LINE__);                    \
  701.             goto exception;                                                            \
  702.             resumeLabel(exception);                                                    \
  703.         }                                                                                    \
  704.     } while (false)
  705.  
  706.  
  707. #else
  708.  
  709. #define require(assertion, exception)                                            \
  710.     do {                                                                                    \
  711.         if (assertion) ;                                                                \
  712.         else {                                                                            \
  713.             goto exception;                                                            \
  714.             resumeLabel(exception);                                                    \
  715.         }                                                                                    \
  716.     } while (false)
  717.  
  718. #endif
  719.  
  720. /*<FF>*/
  721. /*********************************************************************
  722.  
  723. MACRO
  724.     nrequire(assertion, exception)
  725.  
  726. DESCRIPTION
  727.     nrequire will test !assertion and if it fails:
  728.         break into the debugger if debugging is on.
  729.         goto exception.
  730.  
  731. *********************************************************************/
  732.  
  733. #if    __DEBUGSMALL
  734.  
  735. #define nrequire(assertion, exception)                                            \
  736.     do {                                                                                    \
  737.         if (assertion) {                                                                \
  738.             DebugStr();                                                                    \
  739.             goto exception;                                                            \
  740.             resumeLabel(exception);                                                    \
  741.         }                                                                                    \
  742.     } while (false)
  743.  
  744. #elif    DEBUGLEVEL == DEBUGON
  745.  
  746. #define nrequire(assertion, exception)                                            \
  747.     do {                                                                                    \
  748.         void*    __privateAssertion    = (void*)(assertion);                    \
  749.                                                                                             \
  750.         if (__privateAssertion) {                                                    \
  751.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  752.                                     "Exception \"%s\" Raised",                        \
  753.                 #assertion, __privateAssertion, #exception);                    \
  754.             goto exception;                                                            \
  755.             resumeLabel(exception);                                                    \
  756.         }                                                                                    \
  757.     } while (false)
  758.  
  759. #elif DEBUGLEVEL == DEBUGFULL
  760.  
  761. #define nrequire(assertion, exception)                                            \
  762.     do {                                                                                    \
  763.         void*    __privateAssertion    = (void*)(assertion);                    \
  764.                                                                                             \
  765.         if (__privateAssertion) {                                                    \
  766.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  767.                                     "Exception \"%s\" Raised\n"                    \
  768.                                     "File: %s\n"                                        \
  769.                                     "Line: %d",                                            \
  770.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  771.                 __LINE__);                                                                \
  772.             goto exception;                                                            \
  773.             resumeLabel(exception);                                                    \
  774.         }                                                                                    \
  775.     } while (false)
  776.  
  777. #elif DEBUGLEVEL == DEBUGWINDOW
  778.  
  779. #define nrequire(assertion, exception)                                            \
  780.     do {                                                                                    \
  781.         void*    __privateAssertion    = (void*)(assertion);                    \
  782.                                                                                             \
  783.         if (__privateAssertion) {                                                    \
  784.             wprintf(                "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  785.                                     "Exception \"%s\" Raised\n"                    \
  786.                                     "File: %s\n"                                        \
  787.                                     "Line: %d",                                            \
  788.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  789.                 __LINE__);                                                                \
  790.             goto exception;                                                            \
  791.             resumeLabel(exception);                                                    \
  792.         }                                                                                    \
  793.     } while (false)
  794.  
  795. #else
  796.  
  797. #define nrequire(assertion, exception)                                            \
  798.     do {                                                                                    \
  799.         if (assertion) {                                                                \
  800.             goto exception;                                                            \
  801.             resumeLabel(exception);                                                    \
  802.         }                                                                                    \
  803.     } while (false)
  804.  
  805. #endif
  806.  
  807. /*<FF>*/
  808. /*********************************************************************
  809.  
  810. MACRO
  811.     require_action(assertion, exception, action)
  812.  
  813. DESCRIPTION
  814.     require_action will test assertion and if it fails:
  815.         break into the debugger if debugging is on.
  816.         execute action.
  817.         goto exception.
  818.  
  819. *********************************************************************/
  820.  
  821. #if    __DEBUGSMALL
  822.  
  823. #define require_action(assertion, exception, action)                        \
  824.     do {                                                                                    \
  825.         if (assertion) ;                                                                \
  826.         else {                                                                            \
  827.             __DebuggerBreak;                                                            \
  828.             { action }                                                                    \
  829.             goto exception;                                                            \
  830.             resumeLabel(exception);                                                    \
  831.         }                                                                                    \
  832.     } while (false)
  833.  
  834. #elif    DEBUGLEVEL == DEBUGON
  835.  
  836. #define require_action(assertion, exception, action)                        \
  837.     do {                                                                                    \
  838.         if (assertion) ;                                                                \
  839.         else {                                                                            \
  840.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  841.                                     "Exception \"%s\" Raised",                        \
  842.             #assertion, #exception);                                                \
  843.             { action }                                                                    \
  844.             goto exception;                                                            \
  845.             resumeLabel(exception);                                                    \
  846.         }                                                                                    \
  847.     } while (false)
  848.  
  849. #elif DEBUGLEVEL == DEBUGFULL
  850.  
  851. #define require_action(assertion, exception, action)                        \
  852.     do {                                                                                    \
  853.         if (assertion) ;                                                                \
  854.         else {                                                                            \
  855.             dprintf(notrace,    "Assertion \"%s\" Failed\n"                    \
  856.                                     "Exception \"%s\" Raised\n"                    \
  857.                                     "File: %s\n"                                        \
  858.                                     "Line: %d",                                            \
  859.                 #assertion, #exception, __FILE__, __LINE__);                    \
  860.             { action }                                                                    \
  861.             goto exception;                                                            \
  862.             resumeLabel(exception);                                                    \
  863.         }                                                                                    \
  864.     } while (false)
  865.  
  866. #elif DEBUGLEVEL == DEBUGWINDOW
  867.  
  868. #define require_action(assertion, exception, action)                        \
  869.     do {                                                                                    \
  870.         if (assertion) ;                                                                \
  871.         else {                                                                            \
  872.             wprintf(                "Assertion \"%s\" Failed\n"                    \
  873.                                     "Exception \"%s\" Raised\n"                    \
  874.                                     "File: %s\n"                                        \
  875.                                     "Line: %d",                                            \
  876.                 #assertion, #exception, __FILE__, __LINE__);                    \
  877.             { action }                                                                    \
  878.             goto exception;                                                            \
  879.             resumeLabel(exception);                                                    \
  880.         }                                                                                    \
  881.     } while (false)
  882.  
  883. #else
  884.  
  885. #define require_action(assertion, exception, action)                        \
  886.     do {                                                                                    \
  887.         if (assertion) ;                                                                \
  888.         else {                                                                            \
  889.             { action }                                                                    \
  890.             goto exception;                                                            \
  891.             resumeLabel(exception);                                                    \
  892.         }                                                                                    \
  893.     } while (false)
  894.  
  895. #endif
  896.  
  897. /*<FF>*/
  898. /*********************************************************************
  899.  
  900. MACRO
  901.     nrequire_action(assertion, exception, action)
  902.  
  903. DESCRIPTION
  904.     nrequire_action will test !assertion and if it fails:
  905.         break into the debugger if debugging is on.
  906.         execute action.
  907.         goto exception.
  908.  
  909. *********************************************************************/
  910.  
  911. #if    __DEBUGSMALL
  912.  
  913. #define nrequire_action(assertion, exception, action)                        \
  914.     do {                                                                                    \
  915.         if (assertion) {                                                                \
  916.             __DebuggerBreak;                                                            \
  917.             { action }                                                                    \
  918.             goto exception;                                                            \
  919.             resumeLabel(exception);                                                    \
  920.         }                                                                                    \
  921.     } while (false)
  922.  
  923. #elif DEBUGLEVEL == DEBUGON
  924.  
  925. #define nrequire_action(assertion, exception, action)                        \
  926.     do {                                                                                    \
  927.         void*    __privateAssertion    = (void*)(assertion);                    \
  928.                                                                                             \
  929.         if (__privateAssertion) {                                                    \
  930.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  931.                                     "Exception \"%s\" Raised",                        \
  932.                 #assertion, __privateAssertion, #exception);                    \
  933.             { action }                                                                    \
  934.             goto exception;                                                            \
  935.             resumeLabel(exception);                                                    \
  936.         }                                                                                    \
  937.     } while (false)
  938.  
  939. #elif DEBUGLEVEL == DEBUGFULL
  940.  
  941. #define nrequire_action(assertion, exception, action)                        \
  942.     do {                                                                                    \
  943.         void*    __privateAssertion    = (void*)(assertion);                    \
  944.                                                                                             \
  945.         if (__privateAssertion) {                                                    \
  946.             dprintf(notrace,    "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  947.                                     "Exception \"%s\" Raised\n"                    \
  948.                                     "File: %s\n"                                        \
  949.                                     "Line: %d",                                            \
  950.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  951.                 __LINE__);                                                                \
  952.             { action }                                                                    \
  953.             goto exception;                                                            \
  954.             resumeLabel(exception);                                                    \
  955.         }                                                                                    \
  956.     } while (false)
  957.  
  958. #elif DEBUGLEVEL == DEBUGWINDOW
  959.  
  960. #define nrequire_action(assertion, exception, action)                        \
  961.     do {                                                                                    \
  962.         void*    __privateAssertion    = (void*)(assertion);                    \
  963.                                                                                             \
  964.         if (__privateAssertion) {                                                    \
  965.             wprintf(                "Assertion \"!(%s [= %#08X])\" Failed\n"    \
  966.                                     "Exception \"%s\" Raised\n"                    \
  967.                                     "File: %s\n"                                        \
  968.                                     "Line: %d",                                            \
  969.                 #assertion, __privateAssertion, #exception, __FILE__,        \
  970.                 __LINE__);                                                                \
  971.             { action }                                                                    \
  972.             goto exception;                                                            \
  973.             resumeLabel(exception);                                                    \
  974.         }                                                                                    \
  975.     } while (false)
  976.  
  977. #else
  978.  
  979. #define nrequire_action(assertion, exception, action)                        \
  980.     do {                                                                                    \
  981.         if (assertion) {                                                                \
  982.             { action }                                                                    \
  983.             goto exception;                                                            \
  984.             resumeLabel(exception);                                                    \
  985.         }                                                                                    \
  986.     } while (false)
  987.  
  988. #endif
  989.     
  990. /*<FF>*/
  991. /*********************************************************************
  992.  
  993. MACRO
  994.     resume(exception)
  995.  
  996. DESCRIPTION
  997.     resume will resume execution after the n/require/_action statement
  998.     specified by exception. Resume lables must be on (the default) in
  999.     order to use resume. If an action form of require was used then the
  1000.     action will not be re-executed.
  1001.  
  1002. *********************************************************************/
  1003.  
  1004.  
  1005. #define resume(exception)                                                            \
  1006.     do {                                                                                    \
  1007.         goto resume_ ## exception;                                                    \
  1008.     } while (false)
  1009.  
  1010.  
  1011. /*<FF>*/
  1012. /********************************************************************/
  1013.  
  1014. #endif